/* Filename: slowcat.c
 * Description:
 * Last modified: humble 20200329 22:08
 */
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>
#include <signal.h>

#define CPS (10)
#define BUFLEN CPS

static volatile int loop = 0;

void usage(void)
{
    printf("Usage:...\n");
}

static void alrm_handler(int s)
{
    alarm(1);
    loop = 1;
}

int main(int argc, char **argv)
{
    int wrcnt = 3,
        pos = 0;
    int sfd = 0,
        dfd = 1;
    ssize_t rdlen = 0,
            wrlen = 0;
    char buf[BUFLEN] = {0};

    if(argc != 2){
        fprintf(stderr, "argc != 2\n");
        usage();
        exit(1);
    }

    signal(SIGALRM, alrm_handler);
    alarm(1);

    do{
        sfd = open(argv[1], O_RDONLY);
        if(sfd < 0){
            if(errno != EINTR){
                fprintf(stderr, "sfd\n");
                usage();
                exit(1);
            }
        }
    }while(sfd < 0);

    while(1){
        while(!loop)
            pause();
        loop = 0;

        while((rdlen = read(sfd, buf, BUFLEN)) < 0){
            if(errno == EINTR){
                continue;
            }
            fprintf(stderr, "rdlen < 0\n");
            break;
        }
        if(rdlen == 0){
            break;
        }

        pos = 0;
        wrcnt = 3;
        while(rdlen > 0){
            if(--wrcnt < 0){
                fprintf(stderr, "write failed\n");
                exit(1);
            }

            wrlen = write(dfd, buf + pos, rdlen);
            if(wrlen < 0){
                if(errno == EINTR){
                    continue;
                }
                fprintf(stderr, "wrlen < 0\n");
                exit(1);
            }
            pos += wrlen;
            rdlen -= wrlen;
        }
    }

    close(sfd);
    return 0;
}
